package gs.eisenhower.swallet.ui_component;

import gs.eisenhower.swallet.R;
import gs.eisenhower.swallet.dao.BudgetDao;
import gs.eisenhower.swallet.dao.BudgetDaoImpl;
import gs.eisenhower.swallet.dao.CategoryDao;
import gs.eisenhower.swallet.dao.CategoryDaoImpl;
import gs.eisenhower.swallet.model.Budget;
import gs.eisenhower.swallet.model.Category;
import gs.eisenhower.swallet.model.Wallet;
import gs.eisenhower.swallet.utility.FinanceType;
import gs.eisenhower.swallet.utils.constants.WalletConstants;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class ExpendituresFragment extends Fragment {
    private double budgetAmount;
    private List<String> categories;
    private ArrayAdapter<String> adapter;
    private final int requestedCode = 1;
    private CategoryDao categoryTransaction;
    private BudgetDao budgetTransaction;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_expenditures, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        categoryTransaction = new CategoryDaoImpl();
        budgetTransaction = new BudgetDaoImpl();

        loadSpinnerData();

        double budgetAmountLeft = budgetTransaction.read();
        updateBudgetAmountTextView(budgetAmountLeft);

        Button addTransactionButton = (Button) getView().findViewById(R.id.addTransactionButton);
        addTransactionButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (noNewAmount()) {
                    return;
                }
                double newAmount = getSpentAmount();
                double actualAmount = budgetAmount - newAmount;
                if (actualAmount < 0) {
                    String title = "No such amount";
                    String message = "You want to spent a bigger amount than you have";
                    showAlertDialog(title, message);
                    return;
                }
                addNewExpenditure(newAmount);
                refreshBudgetAmount(actualAmount);

                resetAllFields();
                updateBudgetAmountTextView(actualAmount);

                String title = "New spent amount";
                String message = "You spent " + newAmount + WalletConstants.SPACE + WalletConstants.CURRENCY_CODE;
                showAlertDialog(title, message);
            }
        });

        Button editCategoriesButton = (Button) getView().findViewById(R.id.editButton);
        editCategoriesButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getView().getContext(), CategoryListView.class);
                intent.putStringArrayListExtra("Categories", (ArrayList<String>) categories);
                intent.putExtra("Entity", FinanceType.Expenditure.name());
                startActivityForResult(intent, requestedCode);
            }
        });
    }

    private void addNewExpenditure(double newAmount) {
        Wallet newExpenditure = new Wallet();
        newExpenditure.setCategory(getCategory());
        newExpenditure.setDetails(getDetails());
        newExpenditure.setAmount(newAmount);
        newExpenditure.setType(FinanceType.Expenditure.name());
        budgetTransaction.create(newExpenditure);
    }

    private void refreshBudgetAmount(double actualAmount) {
        Date now = new Date();
        SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yy");
        SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss");

        StringBuilder dateStringBuilder = new StringBuilder();
        dateStringBuilder.append(timeFormatter.format(now));
        dateStringBuilder.append(WalletConstants.SPACE);
        dateStringBuilder.append(dateFormatter.format(now));

        Budget updatedBudget = new Budget();
        updatedBudget.setAmount(actualAmount);
        updatedBudget.setTransactionDate(dateStringBuilder.toString());
        budgetTransaction.create(updatedBudget);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == requestedCode) {
            List<String> updatedCategoryList = new ArrayList<String>(data.getStringArrayListExtra("Categories"));
            categories.clear();
            categories.addAll(updatedCategoryList);
            adapter.notifyDataSetChanged();
        }
    }

    private void loadSpinnerData() {
        Spinner spinner = (Spinner) getView().findViewById(R.id.categorySpinner);

        Category category = new Category();
        category.setType(FinanceType.Expenditure.name());

        categories = new ArrayList<String>(categoryTransaction.read(category));
        adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.spinner_item, categories);
        adapter.setDropDownViewResource(R.layout.spinner_item);
        spinner.setAdapter(adapter);
    }

    private void updateBudgetAmountTextView(double amount) {
        budgetAmount = amount;
        TextView textView = (TextView) getView().findViewById(R.id.budgetTextView);
        String localeValue = NumberFormat.getInstance().format(amount);

        String text = "Budget Left: " + localeValue + WalletConstants.SPACE + WalletConstants.CURRENCY_CODE;
        textView.setText(text);
    }

    private double getSpentAmount() {
        EditText editText = (EditText) getView().findViewById(R.id.amountSpentEditText);
        String editTextString = editText.getText().toString();

        if (editTextString.equals("")) {
            return 0.0;
        } else {
            double spentAmount = Double.parseDouble(editText.getText().toString());
            return spentAmount;
        }
    }

    private String getCategory() {
        Spinner spinner = (Spinner) getView().findViewById(R.id.categorySpinner);
        return spinner.getSelectedItem().toString();
    }

    private String getDetails() {
        EditText editText = (EditText) getView().findViewById(R.id.detailsEditText);
        return editText.getText().toString();
    }

    /**
     * Shows a pop-up to warn user if spent amount
     * is empty (required field), else does nothing
     * 
     * @return
     */
    private boolean noNewAmount() {
        if (getSpentAmount() == 0) {
            String title = "No spent amount";
            String message = "Type amount to perform a new transaction";
            showAlertDialog(title, message);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Clear spent amount and details text edit
     */
    private void resetAllFields() {
        EditText detailsEditText = (EditText) getView().findViewById(R.id.detailsEditText);
        detailsEditText.setText("");

        EditText amountSpentEditText = (EditText) getView().findViewById(R.id.amountSpentEditText);
        amountSpentEditText.setText("");
    }

    private void showAlertDialog(String title, String message) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getView().getContext());

        alertDialogBuilder.setTitle(title);
        alertDialogBuilder.setMessage(message);
        alertDialogBuilder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();
    }
}
